#include <iostream>
#include <opencv2/opencv.hpp>
#include "GxIAPI.h"
#include "DxImageProc.h"

using namespace cv;
using namespace std;

int main()
{
    /*
     * test opencv
    Mat src;
    VideoCapture cap(0);
    if(!cap.isOpened())
    {
        cout << "Camera Open filed......" << endl;
        return 0;
    }
    while(1)
    {
        cap >> src;
        imshow("image", src);
        waitKey(10);
    }
    */
    GX_STATUS status = GX_STATUS_SUCCESS;
    bool AcquisitionFlag = true;

    status = GXInitLib();
    if(status != GX_STATUS_SUCCESS)
    {
        cout << "GxInitLib failed..." << endl;
        return 0;
    }
    else
        cout << "GXInitLib Success..." << endl;

    // enumerate cameras and get information
    uint32_t nDeviceNum = 0;
    GX_OPEN_PARAM stOpenParam;
    GX_DEV_HANDLE hDevice = NULL;
    status = GXUpdateDeviceList(&nDeviceNum, 1000);
    if(status == GX_STATUS_SUCCESS && nDeviceNum > 0)
    {
//        GX_DEVICE_BASE_INFO *pBaseinfo = new GX_DEVICE_BASE_INFO[nDeviceNum];
//        uint32_t nSize = nDeviceNum * sizeof(GX_DEVICE_BASE_INFO);

//        //Gets  the basic information of all devices.
//        status = GXGetAllDeviceBaseInfo(pBaseinfo, &nSize);
//        delete []pBaseinfo;
//        GX_DEV_HANDLE hDevice = NULL;

//        stOpenParam.accessMode = GX_ACCESS_EXCLUSIVE;
//        stOpenParam.openMode = GX_OPEN_SN;
//        stOpenParam.pszContent = "KE0210010002";

//        status = GXOpenDevice(&stOpenParam, &hDevice);

//        if(status == GX_STATUS_SUCCESS)
//        {
//            cout << "Open Camera success..." << endl;
//        }
//        else
//            cout << "Open camera failed..." << endl;

//        status = GXCloseDevice(hDevice);
        cout << "GXUpdateDeviceList success..." << endl;
    }
    else
    {
        cout << "GXUpdateDeviceList failed..." << endl;
        return 0;
    }

    status = GXOpenDeviceByIndex(1, &hDevice);
    if (status == GX_STATUS_SUCCESS)
    {

        PGX_FRAME_BUFFER pFrameBuffer;

        status = GXStreamOn(hDevice);
        if (status == GX_STATUS_SUCCESS)
        {
            cout << "Stream On..." << endl;
            while(AcquisitionFlag)
            {
                status = GXDQBuf(hDevice, &pFrameBuffer, 1000);
                if (pFrameBuffer->nStatus == GX_FRAME_STATUS_SUCCESS)
                {
                    //cout << "Image acquisition succeeded..." << endl;
                    cout << "Image processing ..." << endl;
                    cv::Mat src;
                    src.create(pFrameBuffer->nHeight, pFrameBuffer->nWidth, CV_8UC3);
                    uchar* pBGRBuf = NULL;
                    pBGRBuf = new uchar[pFrameBuffer->nHeight * pFrameBuffer->nWidth * 3];

                    //Convert raw8(bayer) image into BGR24 image
                    VxInt32 emDXStatus = DX_OK;
                    emDXStatus = DxRaw8toRGB24((unsigned char*)pFrameBuffer->pImgBuf, pBGRBuf, pFrameBuffer->nWidth, pFrameBuffer->nHeight,
                                                RAW2RGB_NEIGHBOUR, DX_PIXEL_COLOR_FILTER(BAYERBG), false);
                    if(emDXStatus != DX_OK)
                    {
                        cout << "DxRaw8toRGB24 Failed, Error Code: %d" << endl;
                        delete[] pBGRBuf;
                        pBGRBuf = NULL;
                        continue;
                    }
                    else
                    {
                        cout << "copy to Mat..." << endl;
                        memcpy(src.data, pBGRBuf, pFrameBuffer->nHeight*pFrameBuffer->nWidth*3);
                        cv::imshow("image", src);
                        //waitKey(10);
                        delete[] pBGRBuf;
                        pBGRBuf = NULL;
                    }
                    status = GXQBuf(hDevice, pFrameBuffer);
                }
            }
            cout << "exit while loop..." << endl;
        }

        status = GXStreamOff(hDevice);
        cout << "Stream Off ..." << endl;
    }

    status = GXCloseDevice(hDevice);
    cout << "Close Device..." << endl;
    status = GXCloseLib();
    cout << "Close Lib" << endl;
    return 0;
}
